package com.sweet.pack;

import com.sweet.collection.CollectionUtil;
import com.sweet.enums.Charset;
import com.sweet.git.GitUtil;
import com.sweet.image.ResizeImage;
import com.sweet.io.file.FileUtil;
import com.sweet.json.JsonUtil;
import com.sweet.lang.ArrayUtil;
import com.sweet.lang.StringUtil;
import com.sweet.util.ConvertUtil;
import lombok.Getter;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 文件拷贝
 *
 * @author limi
 * @date 2022-09-27 14:19
 */
public class FileCopy {
    /**
     * 配置定义
     */
    private static final List<CopyMap> CONFIGS = new ArrayList<>();

    /**
     * 配置资源产销原因配置
     */
    private static final List<CopyMap> RESOURCE_REASONS = new ArrayList<>();

    /**
     * 工程地址
     */
    private static final List<String> PROJECTS = new ArrayList() {{
        //工程地址
        add("D:/work/gm/rb_client");
        add("D:/work/gm/rb_tool");
    }};

    /**
     * 图片最大宽度
     */
    private static final int IMAGE_MAX_WIDTH = 500;

    /**
     * 图片后缀限制
     */
    private static final Set<String> IMAGE_SUFFIX = new HashSet() {{
        add(".gif");
        add(".png");
        add(".jpg");
    }};

    /**
     * 配置后缀限制
     */
    private static final Set<String> CONFIG_SUFFIX = new HashSet() {{
        add(".json");
    }};

    /**
     * GM后台资源
     */
    private static final String GM_ASSETS = "D:/work/gm/rb_admin/assets";

    static {
        //==RB-山海镜花==//
        String shjhProject = GM_ASSETS + "/shjh";
        String shjhIconSvn = "D:/work/gm/rb_client/Assets/App/Pro/GameRes/UI";
        String shjhJsonSvn = "D:/work/gm/rb_tool/autogen_output/static_json";

        //拷贝icon
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/FolderLoad/RoleIcon/icon_77x77",
                        shjhIconSvn + "/FolderLoad/ItemIcon",
                        shjhIconSvn + "/Module/title/config"
                ),
                shjhProject + "/zh_CN/images"
        ));
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/FolderLoad/RoleIcon/icon_77x77",
                        shjhIconSvn + "/FolderLoad/ItemIcon",
                        shjhIconSvn + "/Module/title/config"
                ),
                shjhProject + "/zh_TW/images"
        ));
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/FolderLoad_TW/RoleIcon/icon_77x77",
                        shjhIconSvn + "/FolderLoad_TW/ItemIcon",
                        shjhIconSvn + "/Module_TW/title/config"
                ),
                shjhProject + "/zh_TW/images"
        ));

        //拷贝活动资源
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/Module/common",
                        shjhIconSvn + "/Module/activity",
                        shjhIconSvn + "/Module/activityEntry/config",
                        shjhIconSvn + "/Background"
                ),
                shjhProject + "/zh_CN/images/activity"
        ));
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/Module/common",
                        shjhIconSvn + "/Module/activity",
                        shjhIconSvn + "/Module/activityEntry/config",
                        shjhIconSvn + "/Background"
                ),
                shjhProject + "/zh_TW/images/activity"
        ));
        CONFIGS.add(new CopyMap(
                Arrays.asList(
                        shjhIconSvn + "/Module_TW/common",
                        shjhIconSvn + "/Module_TW/activity",
                        shjhIconSvn + "/Module_TW/activityEntry/config",
                        shjhIconSvn + "/Background_TW"
                ),
                shjhProject + "/zh_TW/images/activity"
        ));

        //拷贝json配置
        CONFIGS.add(new CopyMap(
                Arrays.asList(shjhJsonSvn),
                shjhProject + "/zh_CN/config"
        ));
        CONFIGS.add(new CopyMap(
                Arrays.asList(shjhJsonSvn),
                shjhProject + "/zh_TW/config"
        ));

        //资源产消
        RESOURCE_REASONS.add(new CopyMap(
                //仅限一个文件
                Arrays.asList("D:/work/gm/rb_tool/table/TableGen/10_ProtobufDef/basicsDef.proto"),
                shjhProject + "/zh_CN/config/ResourceReason.json"
        ));
        RESOURCE_REASONS.add(new CopyMap(
                //仅限一个文件
                Arrays.asList("D:/work/gm/rb_tool/table/TableGen/10_ProtobufDef/basicsDef.proto"),
                shjhProject + "/zh_TW/config/ResourceReason.json"
        ));
    }

    static {
//        //==T3-未尽行夜==//
//        String wjxyProject = GM_ASSETS + "/wjxy";
//        String wjxyIconSvn = "D:/manage/svn/wjxy/icon";
//
//        //拷贝icon
//        CONFIGS.add(new CopyMap(
//                Arrays.asList(wjxyIconSvn + "/Item"),
//                wjxyProject + "/zh_CN/images/Item"
//        ));
//        CONFIGS.add(new CopyMap(
//                Arrays.asList(wjxyIconSvn + "/Head"),
//                wjxyProject + "/zh_CN/images/Head"
//        ));
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        //更新git
        for (String project : PROJECTS) {
            GitUtil.pull(project);
        }

        //待压缩图片
        List<File> resizeImages = new ArrayList();

        //错误信息
        List<String> errors = new ArrayList<>();

        //分批拷贝
        int count = 0;
        for (CopyMap map : CONFIGS) {
            for (String from : map.getFroms()) {
                try {
                    count += copy(from, map.getTo(), resizeImages);
                } catch (Exception e) {
                    errors.add("拷贝发生异常,from=" + from + ",to=" + map.getTo() + ",message=" + e.getMessage());
                    e.printStackTrace();
                }
            }
        }

        //资源产消原因
        for (CopyMap map : RESOURCE_REASONS) {
            File fromFile = new File(map.getFroms().get(0));
            File toFile = new File(map.getTo());
            if (toFile.exists() && toFile.isFile() && toFile.lastModified() >= fromFile.lastModified()) {
                //System.out.println("已跳过：" + toFile.getAbsolutePath());
                continue;
            }

            //开始拷贝文件
            System.out.println("正在拷贝：" + fromFile.getAbsolutePath());

            try {
                writeResourceReasonFile(fromFile, toFile);
            } catch (Exception e) {
                errors.add("拷贝发生异常,from=" + fromFile.getAbsolutePath() + ",to="
                        + toFile.getAbsolutePath() + ",message=" + e.getMessage());
                e.printStackTrace();
            }
        }

        //开始压缩
        resize(resizeImages);

        System.out.println("拷贝异常：" + (errors.size() == 0 ? "无" : JsonUtil.toJson(errors)));
        System.out.println("拷贝总数：" + count + "，耗时：" + (System.currentTimeMillis() - start) + "毫秒");
        System.out.println("拷贝时间：" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
    }

    /**
     * 解析资源原因
     *
     * @param from
     * @param toFile
     */
    public static void writeResourceReasonFile(File from, File toFile) {
        //获取文件内容
        String content = FileUtil.readFileToString(from, Charset.UTF8);
        if (StringUtil.isBlank(content)) {
            throw new RuntimeException("文件内容为空!file=" + from.getAbsolutePath());
        }

        int startIndex = content.indexOf("ELogResReason");
        if (startIndex == -1) {
            throw new RuntimeException("枚举ELogResReason未定义!file=" + from.getAbsolutePath());
        }

        int endIndex = content.indexOf("}", startIndex);
        if (endIndex == -1) {
            throw new RuntimeException("枚举ELogResReason结尾识别错误!file=" + from.getAbsolutePath());
        }

        //获取配置
        String configText = content.substring(startIndex, endIndex);
        if (StringUtil.isBlank(configText)) {
            throw new RuntimeException("枚举ELogResReason内容为空!file=" + from.getAbsolutePath());
        }

        //按行拆分
        List<String> lineTexts = StringUtil.splitToStringListByNewline(configText);
        if (CollectionUtil.isEmpty(lineTexts)) {
            throw new RuntimeException("枚举ELogResReason拆分失败!file=" + from.getAbsolutePath());
        }

        List<Map<String, Object>> reasons = new ArrayList<>();
        for (String line : lineTexts) {
            if (StringUtil.isBlank(line)) {
                continue;
            }

            //截取枚举值
            int lineStartIndex = line.indexOf("=");
            if (lineStartIndex == -1) {
                continue;
            }

            int lineEndIndex = line.indexOf(";", lineStartIndex);
            if (lineEndIndex == -1) {
                continue;
            }

            int id = ConvertUtil.toInt(line.substring(lineStartIndex + 1, lineEndIndex).trim(), 0);
            if (id == 0) {
                continue;
            }

            //获取描述
            String[] splits = line.split("//");
            if (splits == null || splits.length < 2) {
                continue;
            }

            reasons.add(new HashMap() {{
                this.put("id", id);
                this.put("name", splits[1].trim().replace(";", ""));
            }});
        }

        if (reasons.size() == 0) {
            throw new RuntimeException("枚举ELogResReason内容解析失败!file=" + from.getAbsolutePath());
        }

        FileUtil.writeStringToFile(toFile, JsonUtil.toJson(reasons), Charset.UTF8, false);
    }

    /**
     * 图片压缩
     *
     * @param resizeImages 压缩图片列表
     */
    private static void resize(List<File> resizeImages) {
        System.out.println("压缩列表：" + JsonUtil.toJson(resizeImages));
        for (File fromFile : resizeImages) {
            ResizeImage.resizeImage(fromFile, IMAGE_MAX_WIDTH);
        }
    }

    /**
     * 文件拷贝
     *
     * @param fromDir      来源目录
     * @param toDir        目标目录
     * @param resizeImages 待压缩图片列表
     * @return 本次拷贝文件数量
     */
    private static int copy(String fromDir, String toDir, List<File> resizeImages) throws IOException {
        //svn目录
        File from = new File(fromDir);

        //项目存放目录
        File to = new File(toDir);

        //验证目录准确性
        if (!from.exists()) {
            System.out.println("出错：" + "From目录无效!from=" + fromDir);
            return 0;
        }

        //目标目录无效则创建
        if (!to.exists()) {
            to.mkdirs();
        }

        //获取所有文件
        File[] fromFiles = from.listFiles();
        if (ArrayUtil.isEmpty(fromFiles)) {
            return 0;
        }

        //递归遍历
        int count = 0;
        String suffix;
        File toFile;
        for (File fromFile : fromFiles) {
            if (fromFile.isDirectory()) {
                //递归读取
                count += copy(fromFile.getAbsolutePath(), toDir, resizeImages);
            } else {
                //检查后缀
                suffix = FileUtil.getFileSuffix(fromFile.getName()).toLowerCase();
                if (!IMAGE_SUFFIX.contains(suffix) && !CONFIG_SUFFIX.contains(suffix)) {
                    continue;
                }

                //检查文件修改时间
                toFile = new File(to.getAbsolutePath() + "\\" + fromFile.getName());
                if (toFile.exists() && toFile.isFile() && toFile.lastModified() >= fromFile.lastModified()) {
                    //System.out.println("已跳过：" + toFile.getAbsolutePath());
                    continue;
                }

                //开始拷贝文件
                System.out.println("正在拷贝：" + fromFile.getAbsolutePath());
                FileUtils.copyFile(fromFile, toFile);

                //加入压缩图片
                if (IMAGE_SUFFIX.contains(suffix)) {
                    resizeImages.add(toFile);
                }

                count++;
            }
        }

        return count;
    }

    @Getter
    private static class CopyMap {
        /**
         * 来源地址
         */
        private List<String> froms;

        /**
         * 目标地址
         */
        private String to;

        public CopyMap(List<String> froms, String to) {
            this.froms = froms;
            this.to = to;
        }
    }
}